Skip to main content

Deploying Dockerized Applications

This section covers how to deploy Dockerized applications using various methods. We'll cover:

  1. Using Docker Compose to Manage Multi-Container Applications
  2. Deployment Using Pre-built Docker Hub Images
  3. Building and Running an Image from a Dockerfile
  4. Deploying Flask with MySQL, Gunicorn, and Nginx (Detailed production-level deployment)

1. Using Docker Compose to Manage Multi-Container Applications

Scenario: You want to deploy a multi-container application using Docker Compose. In this case, we’ll start with a simple example of deploying an Nginx web server.

Directory Structure:

simple-nginx/
└── docker-compose.yml

docker-compose.yml:

version: '3'
services:
web:
image: nginx:alpine # Pull a lightweight Nginx image from Docker Hub
ports:
- "8080:80" # Map port 8080 on the host to port 80 in the container

Step-by-Step Explanation:

  1. image: nginx:alpine: We’re using the lightweight nginx:alpine image from Docker Hub.
  2. ports: "8080:80": This maps port 8080 on your local machine to port 80 inside the container (which is where Nginx serves its content). This allows you to access the Nginx web server through http://localhost:8080.

How to Deploy:

  1. Create a directory called simple-nginx.
  2. Inside the directory, create a file called docker-compose.yml with the content above.
  3. Run the following command in the same directory:
    docker compose up
  4. Open your browser and go to http://localhost:8080. You should see the default Nginx welcome page.

2. Deploying Flask Application with MySQL

Scenario: Deploying a simple Flask application that connects to a MySQL database using Docker Compose.

Directory Structure:

flask-mysql-app/
├── docker-compose.yml
└── flask-app/
├── Dockerfile
├── app.py
├── requirements.txt

docker-compose.yml:

version: '3'
services:
web:
build: ./flask-app # Build the Flask app from the Dockerfile in the "flask-app" directory
ports:
- "5000:5000" # Map port 5000 on the host to port 5000 inside the container
environment:
- FLASK_ENV=development
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: flask_db
MYSQL_USER: user
MYSQL_PASSWORD: userpassword
ports:
- "3306:3306"

Dockerfile:

# Use the official Python image
FROM python:3.8-slim

# Set the working directory
WORKDIR /app

# Copy current directory contents into /app
COPY . /app

# Install required Python packages
RUN pip install -r requirements.txt

# Command to run the Flask app
CMD ["python", "app.py"]

app.py:

from flask import Flask
import mysql.connector

app = Flask(__name__)

@app.route('/')
def hello():
# Connect to the MySQL database
db = mysql.connector.connect(
host="db", # This matches the MySQL service name in docker-compose
user="user",
password="userpassword",
database="flask_db"
)
return "Connected to MySQL Database!"

if __name__ == "__main__":
app.run(host='0.0.0.0')

requirements.txt:

Flask
mysql-connector-python

Step-by-Step Explanation:

  1. build: ./flask-app: We’re building a custom Flask application defined in the Dockerfile located in the flask-app directory.
  2. depends_on: db: Ensures that the db service (MySQL) starts before the Flask app.
  3. MySQL Configuration: The db service is running a MySQL 5.7 container, with environment variables to configure the root password, database, and user credentials.
  4. Networking: Flask connects to the MySQL service using the hostname db, which is automatically set up by Docker Compose.

How to Deploy:

  1. Create the directory structure as shown above.
  2. Place the docker-compose.yml, Dockerfile, app.py, and requirements.txt in their respective locations.
  3. Run:
    docker compose up --build
  4. Visit http://localhost:5000 to see your Flask app, which connects to the MySQL database.

3. Deploying Using Pre-built Docker Hub Images

Scenario: You want to quickly deploy a Redis server by pulling the official image from Docker Hub.

Directory Structure:

redis-server/
└── docker-compose.yml

docker-compose.yml:

version: '3'
services:
redis:
image: redis:latest # Pull the official Redis image from Docker Hub
ports:
- "6379:6379" # Map port 6379 on the host to port 6379 in the container

Step-by-Step Explanation:

  1. image: redis:latest: This pulls the latest Redis image from Docker Hub.
  2. ports: "6379:6379": This maps port 6379 on your host machine to port 6379 inside the container, which is the default Redis port.

How to Deploy:

  1. Create a directory called redis-server.
  2. Inside that directory, create a file called docker-compose.yml with the content above.
  3. Run:
    docker compose up
  4. Redis will now be running, and you can interact with it at localhost:6379.

4. Advanced Scenario: Deploying Flask with MySQL, Gunicorn, and Nginx

Scenario: You want to deploy a production-ready Flask application that uses MySQL as the database, Gunicorn as the WSGI server, and Nginx as the reverse proxy.

Directory Structure:

flask-gunicorn-nginx/
├── docker-compose.yml
├── flask-app/
│ ├── Dockerfile
│ ├── app.py
│ ├── requirements.txt
└── nginx/
└── nginx.conf

docker-compose.yml:

version: '3'
services:
web:
build: ./flask-app
command: gunicorn -w 4 -b 0.0.0.0:5000 app:app
expose:
- "5000"
depends_on:
- db
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: flask_db
MYSQL_USER: user
MYSQL_PASSWORD: userpassword
ports:
- "3306:3306"
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- web

Dockerfile (Flask App):

# Use the official Python image
FROM python:3.8-slim

# Set the working directory
WORKDIR /app

# Copy current directory contents into /app
COPY . /app

# Install required Python packages
RUN pip install -r requirements.txt

# Command to run the Flask app via Gunicorn
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:5000", "app:app"]

app.py:

from flask import Flask
import mysql.connector

app = Flask(__name__)

@app.route('/')
def hello():
# Connect to the MySQL database
db = mysql.connector.connect(
host="db",
user="user",
password="userpassword",
database="flask_db"
)
return "Hello, world! This is a production-ready Flask app with MySQL and Gunicorn."

if __name__ == "__main__":
app.run(host='0.0.0.0')

requirements.txt:

Flask
gunicorn
mysql-connector-python

nginx.conf:

server {
listen 80;

location / {
proxy_pass http://web:5000; # Proxy to the Gunicorn Flask app
}
}

Step-by-Step Explanation:

  1. Web service: Flask app is served using Gunicorn, which is a production-level WSGI server.
  2. Nginx: Acts as a reverse proxy, forwarding HTTP requests to the Flask app running on Gunicorn.
  3. MySQL: A relational database service to store data, used by the Flask app.
  4. Command gunicorn -w 4 -b 0.0.0.0:5000 app:app: Starts the Gunicorn server with 4 worker processes, listening on port 5000.

How to Deploy:

  1. Set up the directory structure and add the files as shown.
  2. Run the following command to start the application:
    docker compose up --build
  3. Visit http://localhost to see the Flask app served via Nginx.